热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

吴恩达|机器学习作业6.1.SVM建立垃圾邮件分类器

6.1.SVM建立垃圾邮件分类器1)题目:如今,许多电子邮件服务提供垃圾邮件过滤器,能够将电子邮件精确地分类为垃圾邮件和

6.1.SVM建立垃圾邮件分类器


1)题目:

如今,许多电子邮件服务提供垃圾邮件过滤器,能够将电子邮件精确地分类为垃圾邮件和非垃圾邮件。在本部分练习中,您将使用SVM构建自己的垃圾邮件过滤器。
您将训练一个分类器来分类给定的电子邮件x是垃圾邮件(y = 1)还是非垃圾邮件(y = 0)。特别地,你需要将每封电子邮件转换成一个特征向量x∈Rnx\in R^nxRn
本练习中包含的数据集是基于SpamAssassin Public Corpus(http://spamassassin.apache.org/old/publiccorpus/ )的一个子集,对于本练习,您将只使用电子邮件正文(不包括邮件抬头)。
数据集链接: https://pan.baidu.com/s/1cEgQIvehUcLxZ0WVhxcPuQ 提取码: xejn


2)大致步骤:


  • 邮件预处理。首先读取样例邮件查看下。然后进行预处理:
    1.把整封邮件转化为小写
    2.移除所有HTML标签(超文本标记语言)
    3.将所有的URL替换为’httpaddr’
    4.将所有的地址替换为’emailaddr’
    5.将所有数字替换为’number’
    6.将所有美元符号($)替换为’dollar’
    7.将所有单词还原为词根。例如,“discount”, “discounts”, “discounted” and “discounting”都替换为“discount”
    8.移除所有非文字类型,所有的空格(tabs, newlines, spaces)调整为一个空格
    然后再对照单词表得到样例对应的序号列。
  • 提取特征。利用序号列得到邮件的一个特征向量,x∈Rnx\in R^nxRn,这里是一个1899维的特征向量。
  • 训练SVM。取C=0.1,核函数为线性核,用训练集训练出模型,训练精度为99.8%,再在测试集上测试,精度为98.9%。
  • 打印权重最高的前15个词,邮件中出现这些词更容易是垃圾邮件
  • 用训练好的模型预测已给的四封邮件

3)关于Python:


  • .lower( )可以转化为小写。

  • 邮件预处理时需要用到re模块,正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为”元字符”)组成的文字模式。re模块中的函数让你检查一个特定的字符串是否匹配给定的正则表达式(或给定的正则表达式是否匹配特定的字符串,这可归结为同一件事)。
    使用re.sub(pattern, repl, string, count=0, flags=0)
    pattern是需要被替换的部分,repl为替换之后的内容,string为查找的范围,count表示模式匹配后替换的最大次数,默认0表示替换所有的匹配。

  • re.split( ) 用来分割字符串。注意在分割时候不能直接用吴恩达给出的MATLAB的代码,因为有一些需要转义。

  • nltk的全称是natural language tool kit,是一套基于python的自然语言处理工具集。这里主要使用了词干提取的Porter提取算法。nltk.stem.PorterStemmer( )

  • try和except语句块可以用来运行可能会有问题的代码。

  • 在循环中不想要某些条件执行后面的代码可以用continue跳过本次循环直接进行下一次循环。

  • sorted函数直接对数组进行排序,np.argsort是返回排序后的坐标。

  • 关于正则表达式:
    字符”r“的意思是表示忽略后面的转义字符,这样简化了后面正则表达式里每遇到一个转义字符还得挨个转义的麻烦;[ ]里面可以用来填要匹配的字符集;\是转义字符,让它后面的字符还原它原有的含义;*匹配前面的子表达式零次或多次;+匹配前面的子表达式一次或多次;$表示只在字符末尾进行匹配。。。这里引用第一个链接里的一些表格以备后用~
    更多可参考 http://www.runoob.com/regexp/regexp-syntax.html 或 https://blog.csdn.net/u010254900/article/details/22038741


字符描述
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
$匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字符本身,请使用 \$。
( )标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用\( 和 \)。
*匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
+匹配前面的子表达式一次或多次。要匹配 + 字符,请使用\ +。
.匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。
?匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用\ ?。
\将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。
^匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^。
|指明两项之间的一个选择。要匹配 |,请使用 \|。

4) 代码与结果:


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy.io as scio
from sklearn import svm
import re #处理正则表达式的模块
import nltk #自然语言处理工具包'''============================part1 邮件预处理========================='''
#查看样例邮件
f = open('emailSample1.txt', 'r').read()
print(f)def processEmail(email):email &#61; email.lower() #转化为小写email &#61; re.sub(&#39;<[^<>]&#43;>&#39;, &#39; &#39;, email) #移除所有HTML标签email &#61; re.sub(&#39;(http|https)://[^\s]*&#39;, &#39;httpaddr&#39;, email) #将所有的URL替换为&#39;httpaddr&#39;email &#61; re.sub(&#39;[^\s]&#43;&#64;[^\s]&#43;&#39;, &#39;emailaddr&#39;, email) #将所有的地址替换为&#39;emailaddr&#39;email &#61; re.sub(&#39;\d&#43;&#39;, &#39;number&#39;, email) #将所有数字替换为&#39;number&#39;email &#61; re.sub(&#39;[$]&#43;&#39;, &#39;dollar&#39;, email) #将所有美元符号($)替换为&#39;dollar&#39;#将所有单词还原为词根//移除所有非文字类型&#xff0c;空格调整stemmer &#61; nltk.stem.PorterStemmer() #使用Porter算法tokens &#61; re.split(&#39;[ &#64;$/#.-:&*&#43;&#61;\[\]?!()\{\},\&#39;\">_<;%]&#39;, email) #把邮件分割成单个的字符串,[]里面为各种分隔符tokenlist &#61; []for token in tokens:token &#61; re.sub(&#39;[^a-zA-Z0-9]&#39;, &#39;&#39;, token) #去掉任何非字母数字字符try: #porterStemmer有时会出现问题,因此用trytoken &#61; stemmer.stem(token) #词根except:token &#61; &#39;&#39;if len(token) < 1: continue #字符串长度小于1的不添加到tokenlist里tokenlist.append(token)return tokenlist#查看处理后的样例
processed_f &#61; processEmail(f)
for i in processed_f:print(i, end&#61;&#39; &#39;)#得到单词表&#xff0c;序号为索引号&#43;1
vocab_list &#61; np.loadtxt(&#39;vocab.txt&#39;, dtype&#61;&#39;str&#39;, usecols&#61;1)
#得到词汇表中的序号
def word_indices(processed_f, vocab_list):indices &#61; []for i in range(len(processed_f)):for j in range(len(vocab_list)):if processed_f[i]!&#61;vocab_list[j]:continueindices.append(j&#43;1)return indices#查看样例序号
f_indices &#61; word_indices(processed_f, vocab_list)
for i in f_indices:print(i, end&#61;&#39; &#39;)&#39;&#39;&#39;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;part2 提取特征&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#39;&#39;&#39;
def emailFeatures(indices):features &#61; np.zeros((1899))for each in indices:features[each-1] &#61; 1 #若indices在对应单词表的位置上词语存在则记为1return featuressum(emailFeatures(f_indices)) #45&#39;&#39;&#39;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;part3 训练SVM&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#39;&#39;&#39;
#训练模型
train &#61; scio.loadmat(&#39;spamTrain.mat&#39;)
train_x &#61; train[&#39;X&#39;]
train_y &#61; train[&#39;y&#39;]clf &#61; svm.SVC(C&#61;0.1, kernel&#61;&#39;linear&#39;)
clf.fit(train_x, train_y)#精度
def accuracy(clf, x, y):predict_y &#61; clf.predict(x)m &#61; y.sizecount &#61; 0for i in range(m):count &#61; count &#43; np.abs(int(predict_y[i])-int(y[i])) #避免溢出错误得到225return 1-float(count/m) accuracy(clf, train_x, train_y) #0.99825#测试模型
test &#61; scio.loadmat(&#39;spamTest.mat&#39;)
accuracy(clf, test[&#39;Xtest&#39;], test[&#39;ytest&#39;]) #0.989&#39;&#39;&#39;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;part4 高权重词&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#39;&#39;&#39;
#打印权重最高的前15个词,邮件中出现这些词更容易是垃圾邮件
i &#61; (clf.coef_).size-1
while i >1883:#返回从小到大排序的索引&#xff0c;然后再打印print(vocab_list[np.argsort(clf.coef_).flatten()[i]], end&#61;&#39; &#39;)i &#61; i-1&#39;&#39;&#39;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;part5 预测邮件&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#39;&#39;&#39;t &#61; open(&#39;spamSample2.txt&#39;, &#39;r&#39;).read()
#预处理
processed_f &#61; processEmail(t)
f_indices &#61; word_indices(processed_f, vocab_list)
#特征提取
x &#61; np.reshape(emailFeatures(f_indices), (1,1899))
#预测
clf.predict(x)

查看样例邮件
在这里插入图片描述

预处理后的样例&#xff08;吴恩达给出的作业中的样例不对&#xff0c;visitor you re 他给分为visitor your了&#xff0c;这是由于在分割的时候是否把’ 作为分割&#xff0c;这样会导致后面特征提取后少一个非零项&#xff0c;即只有44项&#xff09;
在这里插入图片描述

样例对应的词汇序号
在这里插入图片描述

训练精度和测试精度
在这里插入图片描述

15个权重最高的词&#xff0c;和作业中有些微差别
在这里插入图片描述

测试了给出的四封邮件&#xff0c;都正确分类&#xff0c;下面是spamSample2的结果&#xff0c;分类器把它分为垃圾邮件
在这里插入图片描述

本次作业没有给出知识点概括&#xff0c;因为上次作业6.0已经大概描述清楚了SVM的原理和模型选择的一些内容&#xff0c;这次作业其实主要是对练习怎么从文本中提取特征得到一个n维的特征向量&#xff0c;再进行模型训练。
文本提取和处理也是很难啊~ 继续学吧&#xff01;


推荐阅读
  • Stanford机器学习第九讲. 聚类
    原文:http:blog.csdn.netabcjenniferarticledetails7914952本栏目(Machinelearning)包括单参数的线性回归、多参数的线性 ... [详细]
  • 开发笔记:小白python机器学习之路——支持向量机
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了小白python机器学习之路——支持向量机相关的知识,希望对你有一定的参考价值。支持 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文介绍了在Linux下安装和配置Kafka的方法,包括安装JDK、下载和解压Kafka、配置Kafka的参数,以及配置Kafka的日志目录、服务器IP和日志存放路径等。同时还提供了单机配置部署的方法和zookeeper地址和端口的配置。通过实操成功的案例,帮助读者快速完成Kafka的安装和配置。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文讨论了在shiro java配置中加入Shiro listener后启动失败的问题。作者引入了一系列jar包,并在web.xml中配置了相关内容,但启动后却无法正常运行。文章提供了具体引入的jar包和web.xml的配置内容,并指出可能的错误原因。该问题可能与jar包版本不兼容、web.xml配置错误等有关。 ... [详细]
  • 本文总结了初学者在使用dubbo设计架构过程中遇到的问题,并提供了相应的解决方法。问题包括传输字节流限制、分布式事务、序列化、多点部署、zk端口冲突、服务失败请求3次机制以及启动时检查。通过解决这些问题,初学者能够更好地理解和应用dubbo设计架构。 ... [详细]
  • Tomcat安装与配置教程及常见问题解决方法
    本文介绍了Tomcat的安装与配置教程,包括jdk版本的选择、域名解析、war文件的部署和访问、常见问题的解决方法等。其中涉及到的问题包括403问题、数据库连接问题、1130错误、2003错误、Java Runtime版本不兼容问题以及502错误等。最后还提到了项目的前后端连接代码的配置。通过本文的指导,读者可以顺利完成Tomcat的安装与配置,并解决常见的问题。 ... [详细]
  • .htaccess文件 ... [详细]
  • Python入门后,想要从事自由职业可以做哪方面工作?1.爬虫很多人入门Python的必修课之一就是web开发和爬虫。但是这两项想要赚钱的话 ... [详细]
  • 机器学习之数据均衡算法种类大全+Python代码一文详解
    目录前言一、为什么要做数据均衡?二、数据场景1.大数据分布不均衡2.小数据分布不均衡三、均衡算法类型1.过采样2.欠采样3.组合采样四、算法具体种类1 ... [详细]
  • 使用机器学习的疾病预测原文:https://www.gees ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有